﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using 旅游管理系统.ValidationAttributes;

namespace 旅游管理系统.Dtos
{
    //专门用来处理资源创建数据的输入，用来反序列化输入数据
    [TouristRouteTitleMustBeDifferentFromDescriptionAttribute]
    public abstract class TouristRouteForManipulationDto //是一个抽象类
    {
        // 这个 DTO与另一个DTO相似度那么高，为什么不把这两个DTO合并？而且还能提高代码的可维护性
        //这两个DTO不需要合并，应保持互相独立。一个做输入一个做输出。因为保持两个独立的DTO是为了以后 Model变化的时候尽可能的减小对 UI层的影响
        //不同的请求操作所需要的数据也是不相同的，比如说数据更新的时候，需要的数据量明显要小于数据创建的时候的数据量，而不同的 DTO对数据的验证需求也是不一样的
        //比如说 POST请求可能对产品名称的长度会做一定的要求，而反观 GET请求，数据是从数据库来的，所以根本就不需要对数据进行数据验证，
        // 所以 DTO所对应的是客户端页面的逻辑或者是页面需求，每一页面每一个请求的需求都是不一样的，所以我们要把创建资源和获得资源的DTO要分开，甚至以后还要将资源更新，
        //甚至是部分更新的DTO也要分开，这样才能满足前端不断变化的需求，降低数据输出的颗粒度，

        /// <summary>
        /// 名称或标题
        /// </summary>
        [Required(ErrorMessage = "title 不可为空")] //不能为空
        [MaxLength(100)] //限长
        public string Title { get; set; }
        /// <summary>
        /// 描述、说明
        /// </summary>
        [Required]
        [MaxLength(1500)]
        public virtual string Description { get; set; }
        /// <summary>
        /// 使用计算好的价格来代替原价和折扣，计算方式  原价*折扣
        /// </summary>
        public decimal Price { get; set; }
        /// <summary>
        /// 发布时间
        /// </summary>
        public DateTime CreateTime { get; set; }
        /// <summary>
        /// 更新时间
        /// </summary>
        public DateTime? UpdateTime { get; set; }
        /// <summary>
        /// 出发时间
        /// </summary>
        public DateTime? DepartureTime { get; set; }
        /// <summary>
        /// 买点介绍
        /// </summary>
        public string Features { get; set; }
        /// <summary>
        /// 费用说明
        /// </summary>
        public string Fees { get; set; }
        /// <summary>
        /// 备注
        /// </summary>
        public string Notes { get; set; }
        /// <summary>
        /// 评分
        /// </summary>
        public double? Rating { get; set; }
        /// <summary>
        /// 旅游天数
        /// </summary>
        public string TravelDays { get; set; }
        /// <summary>
        /// 旅游类型
        /// </summary>
        public string TripType { get; set; }
        /// <summary>
        /// 出发地
        /// </summary>
        public string DepartureCity { get; set; }
        //添加嵌套资源，
        public ICollection<TouristRoutePictureForCreationDto> TouristRoutePictures { get; set; } //此处的变量名 touristroutepictures必须与模型类touristroutes中的字段变量名一样，当这两个变量名一样时 automapper会自动进行映射，而当automapper在做映射时会同时对第二级甚至第三级进行映射。所有的这些过程都是由automapper自动进行的
             = new List<TouristRoutePictureForCreationDto>();   //为了变脸出错，给这个变脸加上初始化的值

        ///// <summary>
        ///// 添加接口验证
        ///// </summary>
        ///// <param name="validationContext"></param>
        ///// <returns></returns>
        ///// <exception cref="NotImplementedException"></exception>
        //public IEnumerable<ValidationResult> Validate(
        //    ValidationContext validationContext) //验证的上下文关系对象validationContext：可以提供处理对象所有相关的属性信息以及访问权限
        //{
        //    //可以直接使用DTO对象的数显来访问相关的数据了
        //    if(Title == Description) //当Title 与 Description一样的时候，我们的验证就失败了
        //    {
        //        yield return new ValidationResult(  //yield return可以确保ValidationResult接下来的代码下次调用的时候还会执行，ValidationResult是一个可以提供错误消息并返回类名或者成员变量的名称的对象
        //            "路线名称必须与路线描述不同", //错误信息
        //            new[] { "TouristRouteForCreationDto" } //抛出异常的路径
        //            );
        //    }
        //}
    }
}
